package main

import (
	"fmt"
	"math"
	"math/cmplx"
)

// 函数外部必须使用var等关键字(包内部变量.没有全局变量)
var name = "aqie"

// 定义多个变量
var (
	aa = 1
	bb = 2
	cc = 3
)

func main() {
	fmt.Println("hello world!")
	variableZeroValue()
	variableInitialValue()
	variableTypeDeduction()
	variableShorter()

	fmt.Println(aa, bb, cc)
	euler()

	triangle()
	consts()
	enums()
}

func variableZeroValue() {
	var a int
	var s string
	fmt.Printf("%d %q\n", a, s)
}

func variableInitialValue() {
	var a, b int = 3, 4
	var s string = "aqie"
	fmt.Println(a, b, s)
}

func variableTypeDeduction() {
	var a, b, c, s = 3, 4, true, "aqie"
	fmt.Println(a, b, c, s)
}

func variableShorter() {
	a, b, c, s := 3, 4, true, "aqie" // 第一次定义使用 :=
	c = false
	fmt.Println(a, b, c, s)
}

func euler() {
	c := 3 + 4i
	fmt.Println(cmplx.Abs(c)) // 取模

	fmt.Println(cmplx.Pow(math.E, 1i*math.Pi) + 1) // 欧拉公式 e 的i*π次方
	fmt.Println(cmplx.Exp(1i*math.Pi) + 1)
	fmt.Printf("%.3f\n", cmplx.Exp(1i*math.Pi)+1) // 只要小数点后三位
}

// 类型转换
// c = int(math.Sqrt(float64(a*a + b*b))) // 求平方根(note: float 可能会出现4.9999)
func triangle() {
	var a, b int = 3, 4
	fmt.Println(calcTriangle(a, b))
}

func calcTriangle(a, b int) int {
	// int float64 必须强制转换
	// todo  float 可能出来不是5
	c := int(math.Sqrt(float64(a*a + b*b)))
	return c
}

// 常量
func consts() {
	const filename = "abc.txt" // 也可以使用括号定义一组
	const a, b = 3, 4          // 常量不定义类型类似文本替换,既能做int也能做float
	// const a, b int = 3, 4          // 定义类型
	var c int
	c = int(math.Sqrt(a*a + b*b))
	fmt.Println(c, filename)
}

// 枚举, 直接定义为const, const 必须赋值
func enums() {
	const (
		cpp    = 0
		java   = 1
		python = 2
		golang = 3
	)
	fmt.Println("常量： ", cpp, java, python, golang)

	const (
		spring = iota // 代表自增值枚举类型
		_
		summer
	)
	fmt.Println(spring, summer)

	// 位运算
	const (
		b = 1 << (10 * iota) // 左移 10 * iota, 2 的十次方
		kb
		mb
		gb
		tb
		pb
	)
	fmt.Println(b, kb, mb, gb, tb, pb)
}
